




export default class MjUtils{
    static checkTingPai(seatData: gameSeat, begin, end){
        for(let i = begin; i < end; i++){
            // 如果这张牌已经在胡了，就不用检查了
            if(seatData.tingMap[i] != null){
                continue;
            }

            // 将牌加入到计数中
            let old = seatData.countMap[i];
            if(old == null){
                old = 0;
                seatData.countMap[i] = 1;
            }
            else{
                seatData.countMap[i]++;
            }
            seatData.holds.push(i);
            // 逐个判定手上的牌
            const ret = this.checkCanHu(seatData);
            if(ret){
                // 平胡0番
                seatData.tingMap[i] = {
                    fan: 0,
                    pattern: 'normal',
                };
            }

            // 撤销刚刚加的牌
            seatData.countMap[i] = old;
            seatData.holds.pop();
        }
    }




    static checkCanHu(seatData: gameSeat){
        for(let k in seatData.countMap){
            const c = seatData.countMap[k];
            if(c < 2){
                continue;
            }

            // 如果当前牌大于等于2，则将他选为将牌
            seatData.countMap[k] -= 2;
            //逐个判定剩下的牌是否满足　３Ｎ规则,一个牌会有以下几种情况
            //1、0张，则不做任何处理
            //2、2张，则只可能是与其它牌形成匹配关系
            //3、3张，则可能是单张形成 A-2,A-1,A  A-1,A,A+1  A,A+1,A+2，也可能是直接成为一坎
            //4、4张，则只可能是一坎+单张
            const ret = this.checkSingle(seatData);
            seatData.countMap[k] += 2;
            if(ret){
                return true;
            }
        }
    }


    static checkSingle(seatData: gameSeat){
        const holds = seatData.holds;
        let selected = -1;
        let c = 0;
        for(let i = 0, l = holds.length; i < l; i++){
            const pai = holds[i];
            c = seatData.countMap[pai];
            if( c != 0){
                selected = pai;
                break;
            }
        }

        //  如果没有找到剩余的牌，则标识匹配成功了
        if(selected == -1){
            return true;
        }

        // 否则进行匹配
        if(c == 3){
            // 直接作为一坎
            seatData.countMap[selected] = 0;
            const ret = this.checkSingle(seatData);
            // 立即恢复对数据的修改
            seatData.countMap[selected] = c;
            if(ret){
                return true;
            }
        }
        else if(c == 4){
            // 直接作为一坎
            seatData.countMap[selected] = 1;
            const ret = this.checkSingle(seatData);
            // 立即恢复对数据的修改
            seatData.countMap[selected] = c;
            if (ret) {
                return true;
            }
        }

        // 按单牌处理
        return this.matchSingle(seatData, selected);
    }


    /**检查是否有连续的3张牌 */
    static matchSingle(seatData: gameSeat, selected){
        // 分开配置 A-2， A-1， A
        let matched = true;
        const v = selected % 9;
        if(v < 2){
            matched = false;
        }
        else{
            for(let i = 0; i < 3; i++){
                const t = selected - 2 + i;
                const cc = seatData.countMap[t];
                if(cc == null || cc == 0){
                    matched = false;
                    break;
                }
            }
        }

        // 匹配成功，扣除相应数值
        if(matched){
            seatData.countMap[selected - 2]--;
            seatData.countMap[selected - 1]--;
            seatData.countMap[selected]--;
            const ret = this.checkSingle(seatData);
            seatData.countMap[selected - 2]++;
            seatData.countMap[selected - 1]++;
            seatData.countMap[selected]++;
            if (ret) {
                return true;
            }
        }
        
        // 分开匹配 A-1, A, A+1
        matched = true;
        if(v < 1 || v > 7){
            matched = false;
        }
        else{
            for(let i = 0; i < 3; i++){
                const t = selected - 1 + i;
                const cc = seatData.countMap[t];
                if(cc == null || cc == 0){
                    matched = false;
                    break;
                }
            }
        }

        // 匹配成功，扣除相应数值
        if (matched) {
            seatData.countMap[selected - 1]--;
            seatData.countMap[selected]--;
            seatData.countMap[selected + 1]--;
            const ret = this.checkSingle(seatData);
            seatData.countMap[selected - 1]++;
            seatData.countMap[selected]++;
            seatData.countMap[selected + 1]++;
            if (ret) {
                return true;
            }
        }


        // 分开匹配 A, A+1, A+2
        matched = true;
        if (v > 6) {
            matched = false;
        }
        else {
            for (let i = 0; i < 3; i++) {
                const t = selected + i;
                const cc = seatData.countMap[t];
                if (cc == null || cc == 0) {
                    matched = false;
                    break;
                }
            }
        }

        // 匹配成功，扣除相应数值
        if (matched) {
            seatData.countMap[selected]--;
            seatData.countMap[selected + 1]--;
            seatData.countMap[selected + 2]--;
            const ret = this.checkSingle(seatData);
            seatData.countMap[selected]++;
            seatData.countMap[selected + 1]++;
            seatData.countMap[selected + 2]++;
            if(ret){
                return true;
            }
        }

        return false;
    }
}